from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django import http
from django.conf import settings
from .models import OauthQQUser
from django.contrib.auth import login
from django_redis import get_redis_connection
from users.models import User
import re
import logging

from QQLoginTool.QQtool import OAuthQQ
from meiduo_mall.utils.response_code import RETCODE
from .utils import generate_openid_signature,check_openid_signature
from carts.utils import merge_carts_cookie_to_redis

logger = logging.getLogger()


class OauthQQUrlView(View):
    """qq登录"""

    def get(self, request):
        # 需要响应的内容login_url
        next = request.GET.get('next', '/')
        # 创建qq登录对象
        # QQ_CLIENT_ID = '101518219'
        # QQ_CLIENT_SECRET = '418d84ebdc7241efb79536886ae95224'
        # QQ_REDIRECT_URI = 'http://www.meiduo.site:8000/oauth_callback'
        # def __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=next
        )
        login_url = oauth.get_qq_url()
        print(login_url)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class OauthQQUserView(View):
    """qq用户登录回调处理"""

    def get(self, request):
        code = request.GET.get('code')
        if code is None:
            return http.HttpResponseForbidden('缺少必传参数code')
        # 定义qq登录工具对像
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
        )
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError('qq登录失败')
        # 判断用户是否是已绑定用户
        try:
            user_model = OauthQQUser.objects.get(openid=openid)
        except OauthQQUser.DoesNotExist:
            # 未查询到openid说明为未绑定用户，需要先返回一个绑定页面给前端进行绑定并且先把openid加密保存在前端
            context = {'openid': generate_openid_signature(openid)}
            return render(request, 'oauth_callback.html', context)
        # 查询到说明为绑定用户,返回前要先状态保持,设置cookie
        user = user_model.user
        login(request, user)
        response = redirect(request.GET.get('state') or reverse('contens:index'))
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
        # 合并购物车
        merge_carts_cookie_to_redis(request, response)
        return response

    def post(self, request):
        # 接收前端表单数据
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')
        if not all([mobile, password, sms_code, openid]):
            return http.HttpResponseForbidden('所传参数不全')
        if not re.match(r'1[3-9]\d{9}', mobile):
            return http.HttpResponseForbidden('手机号格式不正确')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('密码格式不正确')
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_code_%s' % mobile)
        redis_conn.delete('sms_code_%s' % mobile)
        if sms_code_server is None:
            return http.HttpResponse('短信验证码已过期')
        if sms_code != sms_code_server.decode():
            return http.HttpResponse('短信验证码输入错误')
        # 判断手机号是否为已存在用户手机号
        try:
            user = User.objects.get(mobile=mobile)
            # 已存在需要判断密码是否正确再绑定openid
            if not user.check_password(password):
                return render(request, 'oauth_callback.html', {'account_errmsg': '账号密码错误'})
        except User.DoesNotExist:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        # 解密openid
        openid = check_openid_signature(openid)
        # 再绑定之前openid可能被篡改或已过期
        if openid is None:
            return http.HttpResponseForbidden('无效的openid')
        # 不管是不是手机号已存在用户都要绑定openid
        OauthQQUser.objects.create(openid=openid, user=user)
        login(request, user)
        response = redirect(request.GET.get('state') or reverse('contents:index'))
        response.set_cookie('username', mobile, max_age=settings.SESSION_COOKIE_AGE)
        # 合并购物车
        merge_carts_cookie_to_redis(request, response)
        return response
